<!DOCTYPE html>
<html lang="en">

<head>
    <script src="https://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js"></script>
    <title>坐标转换</title>
    <style>
    </style>
</head>
<style>
    #demo {
        width: 100%;
    }
</style>

<body>
    <div id="map" class="map">
    </div>
    <input type="text" value="" id="123" placeholder="输入坐标">
    <button onclick="lonlat2PM()">经纬度转平面</button>
    <button onclick="PM2lonlat()">平面转经纬度</button>
    <button onclick="wgs84PM2local()">wgs84平面转地方坐标</button>
    <button onclick="local2wgs84()">地方坐标转wgs84坐标</button>
    <button id="btn">生成显示wgs84坐标</button>
    <div id="demo"></div>
    <script type="text/javascript">
        const centerLongitudeDegree = 114; //中央经线

        function lonlat2PM() {
            let m = document.getElementById("123").value;
            let n = m.split(" ");
            let lon = n[0];
            let lat = n[1];
            const a = 6378137;
            var e2 = 0.0066943799013;
            var projNo = parseInt((Number(lon) + 1.5) / 3);
            var centerLongitudeDegree = projNo * 3;
            var centerLongitudeRadian = (Math.PI / 180) * centerLongitudeDegree; //度转弧度
            var latitudeRadian = (Math.PI / 180) * lat;
            var longtitudeRadian = (Math.PI / 180) * lon;
            var ee = e2 * (1.0 - e2),
                NN = a / Math.sqrt(1.0 - e2 * Math.sin(latitudeRadian) * Math.sin(latitudeRadian)),
                T = Math.tan(latitudeRadian) * Math.tan(latitudeRadian),
                C = ee * Math.cos(latitudeRadian) * Math.cos(latitudeRadian),
                A = (longtitudeRadian - centerLongitudeRadian) * Math.cos(latitudeRadian),
                M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * latitudeRadian - (3 * e2 / 8 + 3 * e2 * e2 /
                    32 + 45 * e2 * e2 * e2 / 1024) * Math.sin(2 * latitudeRadian) + (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 /
                        1024) * Math.sin(4 * latitudeRadian) - (35 * e2 * e2 * e2 / 3072) * Math.sin(6 * latitudeRadian)),
                yval = NN * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * ee) * A * A * A * A * A /
                    120) + 500000,
                xval = M + NN * Math.tan(latitudeRadian) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 -
                    58 * T + T * T + 600 * C - 330 * ee) * A * A * A * A * A * A / 720); //计算X值
            const wgsPM = [xval, yval];
            document.getElementById("demo").innerHTML = wgsPM;
        };

        function PM2lonlat() {
            let m = document.getElementById("123").value;
            let n = m.split(" ");
            let x = n[0];
            let y = Number(n[1]) - 500000;
            const a = 6378137;
            const e2 = 0.0066943799013;
            var centerLongitudeRadian = (Math.PI / 180) * centerLongitudeDegree; //度转弧度

            var e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2)),
                ee = e2 / (1 - e2),
                M = x,
                u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256)),
                fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 /
                    32) * Math.sin(4 * u) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) * Math.sin(
                        8 * u),
                C = ee * Math.cos(fai) * Math.cos(fai),
                T = Math.tan(fai) * Math.tan(fai),
                NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai)),
                R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) * (1 - e2 * Math.sin(fai) * Math.sin(fai)) *
                    (1 - e2 * Math.sin(fai) * Math.sin(fai))),
                D = y / NN,
                //计算经度(Longitude) 纬度(Latitude)
                longtitudeRadian = centerLongitudeRadian + (D - (1 + 2 * T + C) * D * D * D / 6 + (5 - 2 * C + 28 * T - 3 * C *
                    C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / Math.cos(fai),
                latitudeRadian = fai - (NN * Math.tan(fai) / R) * (D * D / 2 - (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D *
                    D * D * D / 24 + (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);

            var latitudeDegree = (180 / Math.PI) * latitudeRadian;
            var longitudeDegree = (180 / Math.PI) * longtitudeRadian;

            const wgsPM1 = [longitudeDegree, latitudeDegree];
            document.getElementById("demo").innerHTML = wgsPM1;
        };

        function wgs84PM2local() {
            let m = document.getElementById("123").value;
            let n = m.split(" ");
            let x = n[0];
            let y = n[1];
            const w = -1493978.966768;
            const b = 1984948.295160;
            const t = 0.999891187945;
            const k = -1.0857294860;
            let coord = [0.0, 0.0];
            let X, Y;
            X = w + x * t * Math.cos(k) - y * t * Math.sin(k);
            Y = b + y * t * Math.cos(k) + x * t * Math.sin(k);
            coord[0] = X;
            coord[1] = Y;
            document.getElementById("demo").innerHTML = coord;
        }

        function local2wgs84PM() {
            let m = document.getElementById("123").value;
            let n = m.split(",");
            let p = n[0];
            let q = n[1];
            const w = 2452839.518919;
            const b = 396183.640998;
            const t = 0.999923358155;
            const k = 1.0857294860;
            let coord = [];
            let X, Y;
            X = w + p * t * Math.cos(k) - q * t * Math.sin(k);
            Y = b + q * t * Math.cos(k) + p * t * Math.sin(k);
            coord[0] = X;
            coord[1] = Y;
            return coord;
        };

        function local2wgs84() {
            const coord = local2wgs84PM();
            let x = coord[0];
            let y = coord[1] - 500000;
            const a = 6378137;
            const e2 = 0.0066943799013;
            const centerLongitudeDegree = 114;
            var centerLongitudeRadian = (Math.PI / 180) * centerLongitudeDegree; //度转弧度
            var e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2)),
                ee = e2 / (1 - e2),
                M = x,
                u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256)),
                fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 /
                    32) * Math.sin(4 * u) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) * Math.sin(
                        8 * u),
                C = ee * Math.cos(fai) * Math.cos(fai),
                T = Math.tan(fai) * Math.tan(fai),
                NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai)),
                R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) * (1 - e2 * Math.sin(fai) * Math.sin(fai)) *
                    (1 - e2 * Math.sin(fai) * Math.sin(fai))),
                D = y / NN,
                //计算经度(Longitude) 纬度(Latitude)
                longtitudeRadian = centerLongitudeRadian + (D - (1 + 2 * T + C) * D * D * D / 6 + (5 - 2 * C + 28 * T - 3 * C *
                    C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / Math.cos(fai),
                latitudeRadian = fai - (NN * Math.tan(fai) / R) * (D * D / 2 - (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D *
                    D * D * D / 24 + (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);
            var latitudeDegree = (180 / Math.PI) * latitudeRadian;
            var longitudeDegree = (180 / Math.PI) * longtitudeRadian;
            const wgsPM1 = [longitudeDegree, latitudeDegree];
            document.getElementById("demo").innerHTML = wgsPM1;
        }
        /**
         * 地方坐标转wgs84坐标
         * @param locationArr
         * @param fourParam
         * @returns {Array}
         */
        window.onload = function () {
            const isArray = function isArray(arr) {
                return Array.isArray(arr)
            }
            const isNumber = function isNumber(number) {
                if (!number && number !== 0) {
                    return false
                }
                return typeof number === 'number'
            }
            const lengthIsNotZero = function lengthIsNotZero(arr) {
                if (!isArray(arr)) {
                    console.error(`传入数据不是数组 ${arr}`)
                    return false
                }
                return arr.length > 0
            }
            const url = "http://47.100.34.182:8203/geoserver/test/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=test%3Aszline1&maxFeatures=500&outputFormat=application%2Fjson"
            const request = new XMLHttpRequest();
            let pointJson;
            request.open("get", url);
            request.send(null);
            request.onload = function () {
                console.log(1);
                if (request.status == 200) {
                    try {
                        pointJson = JSON.parse(request.responseText);
                        // console.log(`转换后的数据为：${forFeatures()}`)
                    } catch (error) {
                        console.log(`json转换失败${error}`)
                    }
                    console.log(`转换后的数据为：${forFeatures()}`)
                } else {
                    console.error(`接口状态码为${request.status}`)
                }
            }
            document.getElementById("btn").onclick = function () {
                showPoint()
            }
            const showPoint = function showPoint() {
                if (!pointJson) {
                    console.error(`暂无数据显示`)
                    return
                }
                const pointChat = forFeatures().map(e => {
                    return e.toString()
                })
                document.getElementById("demo").innerHTML = pointChat.join(";<br />");
            }
            const forFeatures = function forFeatures() {
                const ifRight = pointJson && pointJson.features && isArray(pointJson.features) && lengthIsNotZero(pointJson.features)
                if (!ifRight) {
                    console.error(`数据有问题无法执行`)
                    return
                }
                let locationArr = []
                pointJson.features.forEach((item, index) => {
                    item.geometry.coordinates[0].forEach((e, i) => {
                        // const point = item.geometry.coordinates[0][index] || [null, null]
                        console.log(e)
                        const pointItem = local2wgs84(local2wgs84PM(e[0], e[1], index, i))
                        // console.log("pointItem",pointItem);
                        locationArr.push(pointItem)
                    })
                });
                return locationArr;
            }

            const local2wgs84PM = function local2wgs84PM(x = null, y = null, index = 0) {
                if (!x || !y) {
                    console.warn(`传入数据有问题，默认返回null，位置为：${index}`)
                    return {
                        x: null,
                        y: null
                    }
                }
                if (!isNumber(x) || !isNumber(y)) {
                    console.error(`数据不是数字，无法计算，返回null，位置为：${index}`)
                    return {
                        x: null,
                        y: null
                    }
                }
                const w = 2452839.518919;
                const b = 396183.640998;
                const t = 0.999923358155;
                const k = 1.0857294860;
                let coord = {
                    x: undefined,
                    y: undefined
                };
                coord.x = w + x * t * Math.cos(k) - y * t * Math.sin(k);
                coord.y = b + y * t * Math.cos(k) + x * t * Math.sin(k);
                return coord;
            };

            const local2wgs84 = function local2wgs84(coord = {}) {
                if (!coord.x || !coord.y) {
                    console.warn(`传入数据coord有问题，返回默认null`)
                    return {
                        latitude: null,
                        longtitude: null
                    }
                }
                if (!isNumber(coord.x) || !isNumber(coord.y)) {
                    console.error(`数据coord不是数字，无法计算，返回null`)
                    return {
                        latitude: null,
                        longtitude: null
                    }
                }
                const x = coord.x;
                const y = coord.y - 500000;

                const a = 6378137;
                const e2 = 0.0066943799013;
                const centerLongitudeDegree = 114;
                var centerLongitudeRadian = (Math.PI / 180) * centerLongitudeDegree; //度转弧度
                var e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2)),
                    ee = e2 / (1 - e2),
                    M = x,
                    u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256)),
                    fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 /
                        32) * Math.sin(4 * u) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) * Math.sin(
                            8 * u),
                    C = ee * Math.cos(fai) * Math.cos(fai),
                    T = Math.tan(fai) * Math.tan(fai),
                    NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai)),
                    R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) * (1 - e2 * Math.sin(fai) * Math.sin(fai)) *
                        (1 - e2 * Math.sin(fai) * Math.sin(fai))),
                    D = y / NN,
                    //计算经度(Longitude) 纬度(Latitude)
                    longtitudeRadian = centerLongitudeRadian + (D - (1 + 2 * T + C) * D * D * D / 6 + (5 - 2 * C + 28 * T - 3 * C *
                        C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / Math.cos(fai),
                    latitudeRadian = fai - (NN * Math.tan(fai) / R) * (D * D / 2 - (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D *
                        D * D * D / 24 + (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);
                var latitudeDegree = (180 / Math.PI) * latitudeRadian;
                var longitudeDegree = (180 / Math.PI) * longtitudeRadian;
                const wgsPM1 = [longitudeDegree, latitudeDegree];
                return wgsPM1
            }
        }

    </script>
</body>

</html>